package com.xcity.game.peakroad.combat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.alibaba.fastjson.annotation.JSONField;
import com.xcity.db.entity.Employee;
import com.xcity.db.entity.Player;
import com.xcity.game.combat.AbstractCombatUnit;
import com.xcity.game.combat.CombatTeam;
import com.xcity.game.combat.attr.CombatAttribute;
import com.xcity.game.combat.attr.CombatAttributeType;
import com.xcity.game.combat.skill.CombatSkill;
import com.xcity.game.combat.skill.CombatSkillFactory;
import com.xcity.game.combat.unit.impl.NpcCombatUnit;
import com.xcity.game.common.ConfirmOperation;
import com.xcity.game.employee.Clazz;
import com.xcity.game.employee.EmployeeUtils;
import com.xcity.game.equip.EquipSuit;
import com.xcity.game.equip.suit4.Suit4Factory;
import com.xcity.game.npc.NpcCombatable;
import com.xcity.game.npc.NpcSkill;
import com.xcity.game.peakroad.PeakRoadUtils;
import com.xcity.pomelo.response.EquipmentBagResponse.EquipmentSuit;
import com.xcity.pomelo.response.EquipmentBagResponse.EquipmentSuitEffect;

import naga.x.util.CommonUtils;

public class PeakRoadCombatUnit extends AbstractCombatUnit<PeakRoadCombatable> {
	
	private int id = -1; // npc必须重新生成

	public PeakRoadCombatUnit(CombatTeam team, PeakRoadCombatable combatable, List<CombatAttribute> buffs) {
		super(team, combatable);
		if (combatable.getType() == PLAYER) {
			doInit((Player) combatable.refer);
		} else if (combatable.getType() == EMPLOYEE) {
			doInit((Employee) combatable.refer);
		} else if (combatable.getType() == NPC) {
			doInit((NpcCombatable) combatable.refer);
		}
		doEffect(buffs);
	}
	
	private void doInit() {
		CombatAttributeType[] types = CombatAttributeType.vals;
		for (CombatAttributeType type : types) {
			setAttributeValue(type, combatable.getAttributeValue(type));
		}
	}
	
	private void doInit(Player player) {
		doInit();
//		PlayerSkill skill = player.getSkillManager() != null ? player.getSkillManager().getActivatedSkill() : null;
//		if (skill != null) {
//			this.skills = new ArrayList<CombatSkill>(1);
//			CombatSkill cs = CombatSkillFactory.create(skill.getTemplate());
//			if (cs != null) {
//				this.skills.add(cs);
//			}
//		}
		if (player.getSkillManager() != null) {
			CombatSkill cs = CombatSkillFactory.create(player.getSkillManager().getActive());
			this.skills = Arrays.asList(cs);
			setAttributeValue(CombatAttributeType.MAX_MP, cs.getMp());
		}
	}
	
	private void doInit(Employee employee) {
		doInit();
		// 战士取物攻
		float magicPower = employee.getTemplate().getClazz() == Clazz.WARRIOR ? employee.getAttackPower() : employee.getMagicPower();
		setAttributeValue(CombatAttributeType.MAGIC_POWER, magicPower);
//		List<EmployeeSkill> skills = employee.getSkills();
//		this.skills = new ArrayList<CombatSkill>(2);
//		for (int i = 0; i < skills.size(); i++) {
//			EmployeeSkill skill = skills.get(i);
//			if (skill.getTemplate().isCombatSkill()) {
//				CombatSkill cs = CombatSkillFactory.create(skill.getTemplate());
//				if (cs != null) {
//					this.skills.add(cs);
//				}
//			}
//		}
		CombatSkill cs = CombatSkillFactory.create(employee.getSkillManager().getActive());
		this.skills = Arrays.asList(cs);
		setAttributeValue(CombatAttributeType.MAX_MP, cs.getMp());
		// 4件套
		List<EquipmentSuit> suits = employee.getEquipSuits();
		for (int i = 0; i < suits.size(); i++) {
			List<EquipmentSuitEffect> effects = suits.get(i).effects;
			for (int j = 0; j < effects.size(); j++) {
				EquipmentSuitEffect eff = effects.get(j);
				if (eff.active == ConfirmOperation.YES && eff.type == EquipSuit.SUIT4.type) {
					suit4Calc = Suit4Factory.create(this, eff.template);
					break;
				}
			}
		}
	}
	
	private void doInit(NpcCombatable npc) {
		this.id = NpcCombatUnit.IDS.incrementAndGet();
		doInit();
		// npc物攻/法攻战斗计算时随机数值
		setAttributeValue(CombatAttributeType.ATTACK_POWER, 0);
		setAttributeValue(CombatAttributeType.MAGIC_POWER, 0);
		// 修正npc最大血量
		int hp = getHp();
		if (hp > 0 && getMaxHp() != hp) {
			setAttributeValue(CombatAttributeType.MAX_HP, hp);
		}
		
		List<NpcSkill> npcSkills = npc.getSkills();
		if (npcSkills.isEmpty()) {
			return;
		}
		this.skills = new ArrayList<CombatSkill>(1);
		int i = CommonUtils.randomInt(npcSkills.size());
		CombatSkill cs = CombatSkillFactory.create(npcSkills.get(i));
		if (cs != null) {
			this.skills.add(cs);
			setAttributeValue(CombatAttributeType.MAX_MP, cs.getMp());
		}
	}
	
	@Override
	public long getId() {
		return id != -1 ? id : combatable.getId();
	}
	
	@Override
	@JSONField(serialize = false)
	public float getAttackPower() {
		float val = super.getAttackPower();
		if (combatable.getType() == NPC) {
			val += ((NpcCombatable) combatable.refer).getAttackPower();
		}
		return val;
	}

	@Override
	@JSONField(serialize = false)
	public float getMagicPower() {
		float val = super.getMagicPower();
		if (combatable.getType() == NPC) {
			val += ((NpcCombatable) combatable.refer).getMagicPower();
		}
		return val;
	}
	
	public PeakRoadCombatable refer() {
		return combatable;
	}
	
	private void doEffect(List<CombatAttribute> buffs) {
		if (buffs == null) {
			return;
		}
		for (int i = 0; i < buffs.size(); i++) {
			CombatAttribute buff = buffs.get(i);
			if (buff.getType() != CombatAttributeType.HP) { // hp buff在获得时即刻生效，不需要在这里再次处理
				float value = getAttributeValue(buff.getType());
				setAttributeValue(buff.getType(), PeakRoadUtils.addBuff(value, buff));
			}
		}
	}

	@Override
	public int getQualityLvl() {
		byte type = combatable.getType();
		if (type == PLAYER) {
			return ((Player) combatable.refer()).getQualityLvl();
		}
		if (type == EMPLOYEE) {
			return ((Employee) combatable.refer()).getQualityLvl();
		}
		return 0;
	}

	@Override
	public Clazz getClazz() {
		byte type = combatable.getType();
		if (type == PLAYER) {
			return EmployeeUtils.getPlayerTemplate().getClazz();
		}
		if (type == EMPLOYEE) {
			return ((Employee) combatable.refer()).getTemplate().getClazz();
		}
		return Clazz.WARRIOR;
	}
	
}
